//! 客户端模块综合测试
//! 
//! 为客户端模块提供全面的单元测试和集成测试

use crate::core::*;
use crate::RustCloudConfig;
use std::collections::HashMap;
use std::time::{Duration, SystemTime};
use std::sync::Arc;
use tokio::sync::RwLock;
use async_trait::async_trait;

#[cfg(test)]
mod client_tests {
    use super::*;

    // ============ 配置变更事件测试 ============

    /// 配置事件类型
    #[derive(Debug, Clone, PartialEq)]
    pub enum ConfigEventType {
        /// 配置更新
        Updated,
        /// 配置删除
        Deleted,
        /// 配置创建
        Created,
    }

    /// 配置变更事件
    #[derive(Debug, Clone)]
    pub struct ConfigChangeEvent {
        /// 事件类型
        pub event_type: ConfigEventType,
        /// 环境信息
        pub environment: ConfigEnvironment,
        /// 新配置
        pub new_config: Option<RustCloudConfig>,
        /// 旧配置
        pub old_config: Option<RustCloudConfig>,
        /// 变更时间
        pub timestamp: SystemTime,
    }

    /// 配置客户端错误类型
    #[derive(Debug)]
    pub enum ConfigurationClientError {
        ServerConnectionError(String),
        ConfigurationFetchError(String),
        ConfigFetchError(String),
        CacheError(String),
        WatchError(String),
        SerializationError { source: serde_json::Error },
        CoreError { source: Box<dyn std::error::Error + Send + Sync> },
    }

    impl std::fmt::Display for ConfigurationClientError {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            match self {
                ConfigurationClientError::ServerConnectionError(msg) => write!(f, "服务器连接失败: {}", msg),
                ConfigurationClientError::ConfigurationFetchError(msg) => write!(f, "配置获取失败: {}", msg),
                ConfigurationClientError::ConfigFetchError(msg) => write!(f, "配置获取失败: {}", msg),
                ConfigurationClientError::CacheError(msg) => write!(f, "缓存错误: {}", msg),
                ConfigurationClientError::WatchError(msg) => write!(f, "监听错误: {}", msg),
                ConfigurationClientError::SerializationError { source } => write!(f, "序列化错误: {}", source),
                ConfigurationClientError::CoreError { source } => write!(f, "核心接口错误: {}", source),
            }
        }
    }

    impl std::error::Error for ConfigurationClientError {}

    pub type ClientResult<T> = Result<T, ConfigurationClientError>;

    /// 配置变更监听器trait
    #[async_trait]
    pub trait ConfigChangeListener: Send + Sync {
        /// 处理配置变更事件
        async fn on_config_change(&self, event: ConfigChangeEvent) -> ClientResult<()>;
    }

    #[test]
    fn test_config_change_event_creation() {
        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        let old_config = RustCloudConfig::default();
        let mut new_config = RustCloudConfig::default();
        new_config.application.name = "new-app-name".to_string();

        let event = ConfigChangeEvent {
            event_type: ConfigEventType::Updated,
            environment: environment.clone(),
            new_config: Some(new_config.clone()),
            old_config: Some(old_config.clone()),
            timestamp: SystemTime::now(),
        };

        assert_eq!(event.event_type, ConfigEventType::Updated);
        assert_eq!(event.environment.application, "test-app");
        assert!(event.new_config.is_some());
        assert!(event.old_config.is_some());
    }

    #[test]
    fn test_config_event_types() {
        let events = vec![
            ConfigEventType::Created,
            ConfigEventType::Updated,
            ConfigEventType::Deleted,
        ];

        // 测试事件类型的克隆和比较
        for event_type in events {
            let cloned = event_type.clone();
            assert_eq!(event_type, cloned);
        }
    }

    // ============ Mock配置变更监听器测试 ============

    pub struct MockConfigChangeListener {
        events: Arc<RwLock<Vec<ConfigChangeEvent>>>,
        enabled: bool,
    }

    impl MockConfigChangeListener {
        pub fn new() -> Self {
            Self {
                events: Arc::new(RwLock::new(Vec::new())),
                enabled: true,
            }
        }

        pub fn new_disabled() -> Self {
            Self {
                events: Arc::new(RwLock::new(Vec::new())),
                enabled: false,
            }
        }

        pub async fn get_events(&self) -> Vec<ConfigChangeEvent> {
            self.events.read().await.clone()
        }

        pub async fn clear_events(&self) {
            self.events.write().await.clear();
        }
    }

    #[async_trait]
    impl ConfigChangeListener for MockConfigChangeListener {
        async fn on_config_change(&self, event: ConfigChangeEvent) -> ClientResult<()> {
            if !self.enabled {
                return Err(ConfigurationClientError::WatchError("监听器已禁用".to_string()));
            }

            self.events.write().await.push(event);
            Ok(())
        }
    }

    #[tokio::test]
    async fn test_mock_config_change_listener() {
        let listener = MockConfigChangeListener::new();
        
        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        let event = ConfigChangeEvent {
            event_type: ConfigEventType::Updated,
            environment,
            new_config: Some(RustCloudConfig::default()),
            old_config: None,
            timestamp: SystemTime::now(),
        };

        // 测试事件处理
        listener.on_config_change(event.clone()).await.unwrap();
        
        let events = listener.get_events().await;
        assert_eq!(events.len(), 1);
        assert_eq!(events[0].event_type, ConfigEventType::Updated);
        
        // 测试清除事件
        listener.clear_events().await;
        let events = listener.get_events().await;
        assert_eq!(events.len(), 0);
    }

    #[tokio::test]
    async fn test_mock_config_change_listener_disabled() {
        let listener = MockConfigChangeListener::new_disabled();
        
        let environment = ConfigEnvironment {
            application: "test-app".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        let event = ConfigChangeEvent {
            event_type: ConfigEventType::Updated,
            environment,
            new_config: Some(RustCloudConfig::default()),
            old_config: None,
            timestamp: SystemTime::now(),
        };

        // 禁用状态下应该返回错误
        let result = listener.on_config_change(event).await;
        assert!(result.is_err());
        
        // 确认没有事件被记录
        let events = listener.get_events().await;
        assert_eq!(events.len(), 0);
    }

    // ============ 错误处理测试 ============

    #[test]
    fn test_configuration_client_error_types() {
        let errors = vec![
            ConfigurationClientError::ServerConnectionError("连接失败".to_string()),
            ConfigurationClientError::ConfigurationFetchError("获取失败".to_string()),
            ConfigurationClientError::ConfigFetchError("配置获取失败".to_string()),
            ConfigurationClientError::CacheError("缓存错误".to_string()),
            ConfigurationClientError::WatchError("监听错误".to_string()),
        ];

        for error in errors {
            let error_str = error.to_string();
            assert!(!error_str.is_empty());
        }
    }

    #[test]
    fn test_configuration_client_error_from_conversion() {
        // 测试从其他错误类型的转换
        let json_error = serde_json::from_str::<serde_json::Value>("{invalid json").unwrap_err();
        let client_error = ConfigurationClientError::SerializationError { source: json_error };
        
        match client_error {
            ConfigurationClientError::SerializationError { .. } => {
                // 预期的错误类型
            }
            _ => panic!("unexpected error type"),
        }
    }

    // ============ 集成测试 ============

    #[tokio::test]
    async fn test_multiple_config_change_events() {
        let listener = MockConfigChangeListener::new();
        
        let environment = ConfigEnvironment {
            application: "multi-test".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        // 创建多个不同类型的事件
        let events = vec![
            ConfigChangeEvent {
                event_type: ConfigEventType::Created,
                environment: environment.clone(),
                new_config: Some(RustCloudConfig::default()),
                old_config: None,
                timestamp: SystemTime::now(),
            },
            ConfigChangeEvent {
                event_type: ConfigEventType::Updated,
                environment: environment.clone(),
                new_config: Some(RustCloudConfig::default()),
                old_config: Some(RustCloudConfig::default()),
                timestamp: SystemTime::now(),
            },
            ConfigChangeEvent {
                event_type: ConfigEventType::Deleted,
                environment: environment.clone(),
                new_config: None,
                old_config: Some(RustCloudConfig::default()),
                timestamp: SystemTime::now(),
            },
        ];

        // 处理所有事件
        for event in &events {
            listener.on_config_change(event.clone()).await.unwrap();
        }
        
        let recorded_events = listener.get_events().await;
        assert_eq!(recorded_events.len(), 3);
        
        // 验证事件顺序和类型
        assert_eq!(recorded_events[0].event_type, ConfigEventType::Created);
        assert_eq!(recorded_events[1].event_type, ConfigEventType::Updated);
        assert_eq!(recorded_events[2].event_type, ConfigEventType::Deleted);
    }

    #[tokio::test]
    async fn test_concurrent_event_handling() {
        let listener = Arc::new(MockConfigChangeListener::new());
        let mut handles = vec![];

        let environment = ConfigEnvironment {
            application: "concurrent-test".to_string(),
            profile: "dev".to_string(),
            label: "master".to_string(),
        };

        // 并发处理多个事件
        for _ in 0..10 {
            let listener_clone = listener.clone();
            let env_clone = environment.clone();
            
            let handle = tokio::spawn(async move {
                let event = ConfigChangeEvent {
                    event_type: ConfigEventType::Updated,
                    environment: env_clone,
                    new_config: Some(RustCloudConfig::default()),
                    old_config: None,
                    timestamp: SystemTime::now(),
                };
                
                listener_clone.on_config_change(event).await.unwrap();
            });
            
            handles.push(handle);
        }

        // 等待所有任务完成
        for handle in handles {
            handle.await.unwrap();
        }

        // 验证所有事件都被处理
        let events = listener.get_events().await;
        assert_eq!(events.len(), 10);
    }
}